type NumMap = {
  [key: string]: number;
};
type UnitMap = {
  [key: string]: { value: number; sec: boolean };
};

/**
 * #### 中文数字转换成阿拉伯数字
 * @param chineseStr 中文数字字符串
 * @returns
 * @example
 * ```ts
 * chineseToArabic('一百二十三'); // 123
 * ```
 */
export function chineseToArabic(chineseStr: string) {
  // 定义中文数字和对应的阿拉伯数字
  const numMap: NumMap = {
    零: 0,
    一: 1,
    壹: 1,
    二: 2,
    两: 2,
    贰: 2,
    三: 3,
    叁: 3,
    四: 4,
    肆: 4,
    五: 5,
    伍: 5,
    六: 6,
    陆: 6,
    七: 7,
    柒: 7,
    八: 8,
    捌: 8,
    九: 9,
    玖: 9,
  };
  // 定义中文单位及其对应的阿拉伯数字
  const unitMap: UnitMap = {
    十: { value: 10, sec: false },
    拾: { value: 10, sec: false },
    百: { value: 100, sec: false },
    佰: { value: 100, sec: false },
    千: { value: 1000, sec: false },
    仟: { value: 1000, sec: false },
    万: { value: 10000, sec: true },
    萬: { value: 10000, sec: true },
    亿: { value: 100000000, sec: true },
    億: { value: 100000000, sec: true },
  };
  // 初始化变量
  let total = 0,
    section = 0,
    current = 0,
    hasZero = false;

  // 处理当前段
  const processSection = () => {
    section += current;
    current = 0;
  };

  // 遍历中文数字字符串
  for (const char of chineseStr) {
    // 如果是中文数字
    if (numMap.hasOwnProperty(char)) {
      // 如果是零
      if (char === "零") {
        hasZero = true;
        continue;
      }
      // 如果前面有零
      if (hasZero && current > 0) {
        current *= 10;
        hasZero = false;
      }
      // 加上当前数字
      current += numMap[char];
      // 如果是中文单位
    } else if (unitMap.hasOwnProperty(char)) {
      const unit = unitMap[char];
      // 如果是亿或万
      if (unit.sec) {
        processSection();
        section = (section + current) * unit.value;
        total += section;
        section = 0;
        // 如果是十、百、千
      } else {
        current = current === 0 ? unit.value : current * unit.value;
        section += current;
        current = 0;
      }
      hasZero = false;
    }
  }

  // 处理最后两个字符
  const last2 = chineseStr.slice(-2)[0];
  const last2Unit = unitMap[last2];
  if (last2Unit) {
    current = (current + last2Unit.value) / 10;
  }
  // 返回结果
  return total + section + current;
}
